#ifndef JSONRPCRESPONSE_H
#define JSONRPCRESPONSE_H

#include "JsonRpcMessage.h"
#include <QString>
#include <QJsonObject>
#include <QJsonArray>

/**
 * @brief JSON-RPC 2.0 Response message class
 * 
 * This class represents a JSON-RPC 2.0 response message with result or error.
 * The JSON object store in this class looks like:
 * ====================================
 * |   {                              |
 * |     jsonrpc:"2.0";               |
 * |     id: string | number;         |
 * |     result?: {                   |
 * |       [key: string]: unknown;    |
 * |     }                            |
 * |     error?: {                    |
 * |       code: number;              |
 * |       message: string;           |
 * |       data?: unknown;            |
 * |     }                            |
 * |   }                              |
 * ====================================
 */
class JsonRpcResponse : public JsonRpcMessage
{
public:
    /**
     * @brief Construct a new default JsonRpcResponse object
     */
    explicit JsonRpcResponse();

    /**
     * @brief Construct a new JsonRpcResponse object with ID
     * @param id - The response ID (can be QString or numeric)
     */
    explicit JsonRpcResponse(const QVariant& id);

    /**
     * @brief Destroy the JsonRpcResponse object
     */
    virtual ~JsonRpcResponse();

    /**
     * @brief Get the result value
     * @return QVariant - The result value
     */
    QJsonObject result() const;

    /**
     * @brief Set the result value
     * @param result - The result value
     */
    void setResult(const QJsonObject& result);

    /**
     * @brief Check if the response has a result
     * @return bool - True if result is present, false otherwise
     */
    bool hasResult() const { return !mResult.isEmpty();}

    /**
     * @brief Get the error information
     * @return QJsonObject - The error information
     */
    QJsonObject error() const;

    /**
     * @brief Set the error information
     * @param error - The error information (should be QJsonObject)
     */
    void setError(const QJsonObject& error);

    /**
     * @brief Check if the response has an error
     * @return bool - True if error is present, false otherwise
     */
    bool hasError() const { return mResult.isEmpty();}

    /**
     * @brief Convert the response to JSON object
     * @return QJsonObject - The JSON representation of the response
     */
    QJsonObject toJson() const override;

    /**
     * @brief Create JsonRpcResponse from JSON object
     * @param json - The JSON object to parse
     * @param ok - Optional pointer to store parsing success status
     * @return JsonRpcResponse - The parsed response object
     */
    static JsonRpcResponse fromJson(const QJsonObject& json, bool* ok = nullptr);

    /**
     * @brief Validate the response structure
     * @return bool - True if response is valid, false otherwise
     */
    bool isValid() const override;

private:
    QJsonObject mResult;
    QJsonObject mError;
};

#endif // JSONRPCRESPONSE_H
